package com.gxinyu.needle

import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.setFragmentResult
import androidx.fragment.app.setFragmentResultListener
import androidx.lifecycle.ViewModel
import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter

/**
 * @author gxinyu
 * @date  2022/5/8
 * @desc
 */
abstract class BaseFragment<ViewModelLazy : ViewModel, Binding : ViewBinding> : Fragment(), View.OnClickListener {

    protected lateinit var TAG: String
    protected lateinit var ctx: AppCompatActivity
    protected lateinit var binding: Binding
    protected lateinit var manager: FragmentManager
    protected var requestKey: String? = null
    protected var viewModel: ViewModelLazy? = null

    companion object {
        const val REQUEST_KEY = "requestKey"
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        this.ctx = context as AppCompatActivity
        TAG = this::class.java.simpleName
        manager = ctx.supportFragmentManager
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?,
    ): View? {
        Log.e(TAG, "fragment_onCreateView")
        viewModel = bindViewModel()
        arguments?.let { bindBundle(it) }
        binding = bindLayout()
        initView()
        initData()
        bindObserver()
        bindListener()
        return binding.root
    }

    /**
     * 绑定ViewModel
     * @return ViewModelLazy
     */
    open fun bindViewModel(): ViewModelLazy? = null

    /**
     * 绑定intent
     * @param bundle Bundle
     */
    open fun bindBundle(bundle: Bundle) {
        requestKey = bundle.getString(REQUEST_KEY)
    }

    /**
     * 绑定布局
     * @return View
     */
    abstract fun bindLayout(): Binding

    /**
     * 初始化view
     */
    open fun initView() {

    }

    /**
     * 初始化数据
     */
    open fun initData() {

    }

    /**
     * 重新加载
     */
    open fun onReload() {

    }

    /**
     * 绑定observer
     */
    open fun bindObserver() {

    }

    /**
     * 绑定监听
     */
    open fun bindListener() {

    }

    /**
     * 监听回调
     * @param v View
     */
    override fun onClick(v: View?) {

    }

    /**
     * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     * +++++++++++++++++++++++++++++++++++++++++++++++++fragment回传数据++++++++++++++++++++++++++++++++
     * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     */
    /**
     * 设置回传fragment数据
     * @param args Bundle
     */
    fun onBackResult(args: Bundle) {
        requestKey?.let {
            setFragmentResult(it, args)
            manager.popBackStack()
        }
    }

    interface FragmentResultListener {
        /**
         * Callback used to handle results passed between fragments.
         *
         * @param requestKey key used to store the result
         * @param result result passed to the callback
         */
        fun onFragmentResult(requestKey: String, result: Bundle)
    }


    /**
     * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     * +++++++++++++++++++++++++++++++++++++++++++++++++页面跳转++++++++++++++++++++++++++++++++++++++++
     * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     */
    /**
     * fragment中添加fragment（add方式）
     * @param target Fragment
     * @param args Bundle
     */
    fun start(target: Fragment, args: Bundle? = null) {
        args?.let {
            target.arguments = it
        }
        manager.beginTransaction()
            .setReorderingAllowed(true)
            .add(R.id.fragment_root, target)
            .addToBackStack(target.javaClass.simpleName)
            .commit()
    }

    /**
     * fragment中添加fragment（add方式）
     * @param target Fragment
     * @param args Bundle
     */
    fun start(target: String, args: Bundle? = null) {
        val navigation = ARouter.getInstance().build(target).navigation() as BaseFragment<*, *>
        args?.let {
            navigation.arguments = it
        }
        manager.beginTransaction()
            .setReorderingAllowed(true)
            .add(R.id.fragment_root, navigation)
            .addToBackStack(target.javaClass.simpleName)
            .commit()
    }

    /**
     * fragment中添加fragment（replace方式）
     * @param target Fragment
     * @param args Bundle
     */
    fun replace(target: Fragment, args: Bundle? = null) {
        args?.let {
            target.arguments = it
        }
        manager.beginTransaction()
            .setReorderingAllowed(true)
            .replace(R.id.fragment_root, target)
            .addToBackStack(target.javaClass.simpleName)
            .commit()
    }

    /**
     * fragment中添加fragment（replace方式）
     * @param target Fragment
     * @param args Bundle
     */
    fun startRoot(target: Fragment, args: Bundle? = null) {
        args?.let {
            target.arguments = it
        }
        clearFragmentStack()
        manager.beginTransaction()
            .setReorderingAllowed(true)
            .replace(R.id.fragment_root, target)
            .addToBackStack(target.javaClass.simpleName)
            .commit()
    }

    /**
     * fragment中添加fragment（replace方式）
     * @param target Fragment 目标fragment
     * @param requestKey String 请求key
     * @param args Bundle 携带参数
     * @param resultCallback FragmentResultListener 跳转结果回调
     */
    fun startForResult(target: Fragment, requestKey: String, args: Bundle? = null, resultCallback: FragmentResultListener) {
        val targetArgs: Bundle = args ?: Bundle()
        targetArgs.putString(REQUEST_KEY, requestKey)
        target.arguments = targetArgs
        manager.beginTransaction()
            .setReorderingAllowed(true)
            .add(R.id.fragment_root, target)
            .addToBackStack(tag ?: target.javaClass.simpleName)
            .commit()
        target.setFragmentResultListener(requestKey) { it, bundle ->
            resultCallback.onFragmentResult(it, bundle)
        }
    }

    /**
     * 清空当前栈所有fragment
     */
    private fun clearFragmentStack() {
        val count: Int = manager.backStackEntryCount
        if (count > 0) {
            val entry: FragmentManager.BackStackEntry =
                manager.getBackStackEntryAt(0)
            manager.popBackStack(
                entry.name,
                FragmentManager.POP_BACK_STACK_INCLUSIVE
            )
        }
    }

    /**
     * 退出当前的fragment
     */
    fun onBackPressed() {
        manager.popBackStack()
    }

    /**
     * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     * +++++++++++++++++++++++++++++++++++++++++++++++++生命周期++++++++++++++++++++++++++++++++++++++++
     * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     */
    override fun onResume() {
        super.onResume()
        Log.d(TAG, "fragment_onResume")
    }

    override fun onPause() {
        super.onPause()
        Log.d(TAG, "fragment_onPause")
    }

    override fun onStart() {
        super.onStart()
        Log.d(TAG, "fragment_onStart")
    }

    override fun onStop() {
        super.onStop()
        Log.d(TAG, "fragment_onStop")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(TAG, "fragment_onDestroy")
    }

    override fun onDestroyView() {
        super.onDestroyView()
        Log.d(TAG, "fragment_onDestroyView")
    }

    override fun onDetach() {
        super.onDetach()
        Log.d(TAG, "fragment_onDetach")
    }
}
